package com.alibaba.citrus.cr.order.open.api.facade.service;

import com.alibaba.citrus.cr.common.annotation.FacadeInvoker;
import com.alibaba.citrus.cr.common.log.ModuleEnum;
import com.alibaba.citrus.cr.order.open.api.facade.common.contant.ObjectTypeEnum;
import com.alibaba.citrus.cr.unified.inventory.repository.AllocateApplyOrderReadRepository;
import com.alibaba.citrus.cr.unified.inventory.repository.AllocateOrderReadRepository;
import com.alibaba.citrus.cr.unified.inventory.utils.EnumUtils;
import com.alibaba.citrus.cr.unified.inventory.utils.InfoUtil;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.cz.base.tool.log.model.OpLogDateTypeEnum;
import com.alibaba.cz.base.tool.log.model.OperatorType;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.crplatformenhance.model.dto.OperateLogDiff;
import com.epoch.app.crplatformenhance.model.dto.OperateQueryInfoRequest;
import com.epoch.app.crplatformenhance.queryoperatelog.service.QueryOperateLogService;
import com.epoch.app.crunifiedinventory.dto.request.AllocateOrderRequest;
import com.epoch.app.crunifiedinventory.dto.response.AllocateApplyOrderResponse;
import com.epoch.app.crunifiedinventory.model.enums.AllocateApplyOrderOperationTypeEnum;
import com.epoch.app.crunifiedinventory.sdo.AllocateOrderWithOrderDetailsSDO;
import com.epoch.app.crunifiedinventory.sdo.enums.AllocateApplyOrderStatusEnum;
import com.epoch.app.mninventorycenter.documentlogprocess.service.DocumentLogProcessService;
import com.epoch.app.mninventorycenter.model.dto.DocumentLogRequest;
import com.epoch.app.mninventorycenter.model.dto.DocumentLogResponse;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author yifei
 * @since 2024/3/21
 */
@Service
@Primary
public class DocumentLogProcessServiceImpl implements DocumentLogProcessService {
    private static Log log = Log.getLogger(DocumentLogProcessServiceImpl.class);

    /**
     * 字符串 3
     */
    private static final String THREE_STRING = "3";
    /**
     * 0
     */
    private static final int ZERO = 0;
    private static final int THOUSAND = 1000;
    private static final String CODE = "code";
    private static final String STATUS = "status";
    public static final Integer MAX_PAGE_SIZE = 1000;
    private static final String UNKNOWN = "unknown";
    private static final String SYSTEM = "系统";

    @Resource
    private AllocateApplyOrderReadRepository allocateApplyOrderReadRepository;

    @Resource
    private QueryOperateLogService queryOperateLogService;

    @Resource
    private AllocateOrderReadRepository allocateOrderReadRepository;

    @Override
    @FacadeInvoker(remark = "查询操作日志")
    public Result<List<DocumentLogResponse>> queryDocumentLog(DocumentLogRequest documentLogRequest) {
        log.info("DocumentLogProcessServiceImpl_queryDocumentLog_request:{}", JSON.toJSONString(documentLogRequest));
        if (ObjectTypeEnum.TRANS_APPLY_TYPE.getObjectType() == Integer.parseInt(documentLogRequest.getObjectType())) {
            return transferApplyDocumentLog(documentLogRequest.getObjectCode());
        } else {
            return transferDocumentLog(documentLogRequest.getObjectCode());
        }
    }

    public Result<List<DocumentLogResponse>> transferApplyDocumentLog(String objectCode) {
        OperateQueryInfoRequest operateQueryInfoRequest = new OperateQueryInfoRequest();
        AllocateApplyOrderResponse response = allocateApplyOrderReadRepository.queryAllocateApplyOrderByCode(objectCode);
        if (response != null && response.getAllocateApplyOrderDetailDTO() != null && response.getAllocateApplyOrderDetailDTO().getId() != null) {
            operateQueryInfoRequest.setObjectId(response.getAllocateApplyOrderDetailDTO().getId().toString());
        }
        //object必传
        if (StringUtils.isBlank(operateQueryInfoRequest.getObjectId())) {
            return Result.success(Lists.newArrayList());
        }
        //操作者类型
        operateQueryInfoRequest.setOperatorType(OperatorType.USER.getOperatorType());
        //模块ID 1: 主数据  2:月度计划 3：调拨一盘货 4：预报销售 5：价格  6：活动
        operateQueryInfoRequest.setModuleId(THREE_STRING);
        //模块名称 必传
        operateQueryInfoRequest.setModuleName(ModuleEnum.UNIFIED_INVENTORY.getModuleName());
        //对象名称 查询字段和查询对象二选一
        operateQueryInfoRequest.setObjectName(objectCode);
        //对象ID 如果是对象，填写对象 ID；如果是字段，填写字段的值 前端传
        //数据类型 1：字段类型  2：对象类型
        //使用com.alibaba.cz.base.tool.log.model.OpLogDateTypeEnum中的枚举值
        operateQueryInfoRequest.setDataType(OpLogDateTypeEnum.OBJECT_TYPE.getDataType());
        //是否需要返回新老值
        operateQueryInfoRequest.setNeedReturnNewOldValue(true);
        //起始索引
        operateQueryInfoRequest.setStart(ZERO);
        //页面大小
//        operateQueryInfoRequest.setLimit(TEN);
        operateQueryInfoRequest.setLimit(THOUSAND);
        Result<List<OperateLogDiff>> listResult = queryOperateLogService.queryOperateLogRowDiff(operateQueryInfoRequest);

        String objectDesc = "调拨预报单";
        List<DocumentLogResponse> documentLogResponseList = new ArrayList<>();
        if (Objects.nonNull(listResult) && Objects.nonNull(listResult.getResult())) {
            List<OperateLogDiff> operateLogList = listResult.getResult();
            for (OperateLogDiff operateLogDiff : operateLogList) {
                DocumentLogResponse documentLogResponse = new DocumentLogResponse();
                //创建时间
                documentLogResponse.setGmtCreate(operateLogDiff.getGmt_create());
                //操作人
                String operatorId = operateLogDiff.getOperatorId();
                if ("0".equals(operatorId)) {
                    operatorId = SYSTEM;
                }
                documentLogResponse.setOperator(operatorId);
                //操作类型
                documentLogResponse.setOperationType(EnumUtils.getAllocateApplyOrderOperationTypeEnum(operateLogDiff.getOperateType()));
                String features = operateLogDiff.getFeatures();
                HashMap<String, String> featuresMap = new HashMap();
                if (StringUtils.isNotEmpty(features)) {
                    featuresMap = JSONObject.parseObject(features, HashMap.class);
                }
                //操作内容 修改的要展示出来
                List<String> s = new ArrayList<>();
                //创建
                if (AllocateApplyOrderOperationTypeEnum.CREATE.getValue().equals(operateLogDiff.getOperateType().toString())) {
                    String status = "";
                    if (StringUtils.isNotEmpty(featuresMap.get(STATUS))) {
                        status = EnumUtils.getAllocateApplyOrderStatusEnum(Integer.valueOf(featuresMap.get(STATUS)));
                    }
                    String remark = "创建了" + objectDesc + "(" + featuresMap.get(CODE) + ");状态:" + status;
                    s.add(remark);
                }
                //保存 主单
                if (AllocateApplyOrderOperationTypeEnum.UPDATE.getValue().equals(operateLogDiff.getOperateType().toString())) {
                    String status = "";
                    if (StringUtils.isNotEmpty(featuresMap.get(STATUS))) {
                        status = EnumUtils.getAllocateApplyOrderStatusEnum(Integer.valueOf(featuresMap.get(STATUS)));
                    }
                    String remark = "更新了" + objectDesc + "(" + featuresMap.get(CODE) + ");状态:" + status;
                    s.add(remark);
                }
                //提交
                if (AllocateApplyOrderOperationTypeEnum.SUBMIT.getValue().equals(operateLogDiff.getOperateType().toString())) {
                    String status = "";
                    boolean isHeadquartersReply = false;
                    if (StringUtils.isNotEmpty(featuresMap.get(STATUS))) {
                        status = EnumUtils.getAllocateApplyOrderStatusEnum(Integer.valueOf(featuresMap.get(STATUS)));
                        if (AllocateApplyOrderStatusEnum.SHIPPER_REPLY.getCode().equals(Integer.valueOf(featuresMap.get(STATUS)))) {
                            isHeadquartersReply = true;
                        }
                    }
                    String remark;
                    if (isHeadquartersReply) {
                        documentLogResponse.setOperationType(AllocateApplyOrderOperationTypeEnum.REPLY.getLabel());
                        remark = "回复了" + objectDesc + "(" + featuresMap.get(CODE) + ");状态:" + status;
                    } else {
                        remark = "提交了" + objectDesc + "(" + featuresMap.get(CODE) + ");状态:" + status;
                    }
                    s.add(remark);
                }
                //回复
                if (AllocateApplyOrderOperationTypeEnum.REPLY.getValue().equals(operateLogDiff.getOperateType().toString())) {
                    String status = "";
                    if (StringUtils.isNotEmpty(featuresMap.get(STATUS))) {
                        status = EnumUtils.getAllocateApplyOrderStatusEnum(Integer.valueOf(featuresMap.get(STATUS)));
                    }
                    String remark = "回复了" + objectDesc + "(" + featuresMap.get(CODE) + ");状态:" + status;
                    s.add(remark);
                }
                //取消
                if (AllocateApplyOrderOperationTypeEnum.CANCEL.getValue().equals(operateLogDiff.getOperateType().toString())) {
                    String status = "";
                    if (StringUtils.isNotEmpty(featuresMap.get(STATUS))) {
                        status = EnumUtils.getAllocateApplyOrderStatusEnum(Integer.valueOf(featuresMap.get(STATUS)));
                    }
                    String remark = "取消了" + objectDesc + "(" + featuresMap.get(CODE) + ");状态:" + status;
                    s.add(remark);
                }
                //驳回
                if (AllocateApplyOrderOperationTypeEnum.REJECT.getValue().equals(operateLogDiff.getOperateType().toString())) {
                    String status = "";
                    if (StringUtils.isNotEmpty(featuresMap.get(STATUS))) {
                        status = EnumUtils.getAllocateApplyOrderStatusEnum(Integer.valueOf(featuresMap.get(STATUS)));
                    }
                    String remark = "驳回了" + objectDesc + "(" + featuresMap.get(CODE) + ");状态:" + status;
                    s.add(remark);
                }
                //复制
                if (AllocateApplyOrderOperationTypeEnum.COPY.getValue().equals(operateLogDiff.getOperateType().toString())) {
                    String status = "";
                    if (StringUtils.isNotEmpty(featuresMap.get(STATUS))) {
                        status = EnumUtils.getAllocateApplyOrderStatusEnum(Integer.valueOf(featuresMap.get(STATUS)));
                    }
                    String remark = "复制了" + objectDesc + "(" + featuresMap.get(CODE) + ");状态:" + status;
                    s.add(remark);
                }
                documentLogResponse.setOperationContent(s);
                documentLogResponseList.add(documentLogResponse);
            }
        }
        log.info("DocumentLogProcessServiceImpl_transferApplyDocumentLog_response:{}", JSON.toJSONString(documentLogResponseList));
        return Result.success(documentLogResponseList);
    }

    public Result<List<DocumentLogResponse>> transferDocumentLog(String objectCode) {
        OperateQueryInfoRequest operateQueryInfoRequest = new OperateQueryInfoRequest();
        AllocateOrderRequest request = new AllocateOrderRequest();
        request.setAllocateOrderCode(objectCode);
        AllocateOrderWithOrderDetailsSDO sdo = allocateOrderReadRepository.get(request);
        //操作者类型
//        operateQueryInfoRequest.setOperatorType(OperatorType.USER.getOperatorType());
        //模块ID 1: 主数据  2:月度计划 3：调拨一盘货 4：预报销售 5：价格  6：活动
        operateQueryInfoRequest.setModuleId("3");
        //模块名称 必传
        operateQueryInfoRequest.setModuleName(ModuleEnum.UNIFIED_INVENTORY.getModuleName());
        //对象名称 查询字段和查询对象二选一
        operateQueryInfoRequest.setObjectName(objectCode);
        //对象ID 如果是对象，填写对象 ID；如果是字段，填写字段的值 前端传
        if (sdo != null && sdo.getAllocateOrderSDO() != null && sdo.getAllocateOrderSDO().getId() != null) {
            operateQueryInfoRequest.setObjectId(sdo.getAllocateOrderSDO().getId().toString());
        }
        //object必传
        if (org.apache.commons.lang3.StringUtils.isBlank(operateQueryInfoRequest.getObjectId())) {
            return Result.success(Lists.newArrayList());
        }
        operateQueryInfoRequest.setDataType(OpLogDateTypeEnum.OBJECT_TYPE.getDataType());
        //是否需要返回新老值
        operateQueryInfoRequest.setNeedReturnNewOldValue(true);
        //起始索引
        operateQueryInfoRequest.setStart(0);
        //页面大小
        operateQueryInfoRequest.setLimit(MAX_PAGE_SIZE);
        //获取操作不同
        Result<List<OperateLogDiff>> listResult = queryOperateLogService.queryOperateLogRowDiff(operateQueryInfoRequest);
        List<DocumentLogResponse> documentLogResponseList = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(listResult.getResult())) {
            List<OperateLogDiff> operateLogList = listResult.getResult();
            for (OperateLogDiff operateLogDiff : operateLogList) {
                if (EnumUtils.exclude(operateLogDiff.getOperateType())) {
                    continue;
                }
                DocumentLogResponse dto = new DocumentLogResponse();
                dto.setGmtCreate(operateLogDiff.getGmt_create());
                dto.setOperationType(EnumUtils.getAllocateApplyOrderOperationTypeEnum(operateLogDiff.getOperateType()));
                dto.setOperator(InfoUtil.getRealName(operateLogDiff.getOperatorId()));
                String features = operateLogDiff.getFeatures();
                if (org.apache.commons.lang3.StringUtils.isNotBlank(features)) {
                    Map<String, String> map = JSONObject.parseObject(features, Map.class);
                    if (MapUtils.isNotEmpty(map)) {
                        String content = (UNKNOWN.equals(map.get("name")) ? SYSTEM : map.get("name")) + " " + map.get("active") + "了" + map.get("orderType") + "单(" + map.get("bizNo") + ");状态:" + map.get("status");
                        dto.setOperator(content);
                    }
                }
                documentLogResponseList.add(dto);
            }

        }
        log.info("DocumentLogProcessServiceImpl_transferDocumentLog_response:{}", JSON.toJSONString(documentLogResponseList));
        return Result.success(documentLogResponseList);
    }
}
